<template>
  <div class="chart-container" ref="chartRef"></div>
</template>

<script setup>
/**
 * 漏洞类型统计图表组件
 * @module VulnTypeChart
 * @description 用于展示不同类型的漏洞数量分布条形图
 */
import { ref, onMounted, watch, onUnmounted } from "vue";
import * as echarts from "echarts/core";
import { BarChart } from "echarts/charts";
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
} from "echarts/components";
import { UniversalTransition } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import { getVulnTypeCount } from "@/api/vulnerability";
// 注册必要的组件
echarts.use([
  BarChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  UniversalTransition,
  CanvasRenderer,
]);

const props = defineProps({
  /**
   * 数据来源
   * 1-标准库
   */
  is_standard: {
    type: Number,
    default: 1,
  },
  /**
   * 图表标题
   */
  title: {
    type: String,
    default: "漏洞类型分布",
  },
  /**
   * 图表高度
   */
  height: {
    type: String,
    default: "300px",
  },
  /**
   * 文本颜色
   */
  textColor: {
    type: String,
    default: "#333",
  },
});
// 漏洞产品来源数据
const typeData = ref([]);
async function fetchData(initFlag) {
  if (chartInstance) {
    // 判断是否为暗色主题
    const isDarkTheme = document.documentElement.classList.contains("dark");
    chartInstance.showLoading({
      text: "loading",
      color: isDarkTheme ? "#fff" : "#0073f3",
      textColor: isDarkTheme ? "#fff" : "#000",
      maskColor: isDarkTheme
        ? "rgba(0, 0, 0, 0.5)"
        : "rgba(230, 230, 230, 0.5)",
      zlevel: 0,
    });
  }
  const typeRes = await getVulnTypeCount({ is_standard: props.is_standard });
  typeData.value = typeRes.data.map((item) => ({
    type: item.vuln_type,
    count: item.num_orders,
  }));
  if (chartInstance) {
    chartInstance.hideLoading();
  }
  if (initFlag) {
    initChart();
  } else {
    updateChart();
  }
}
// 图表DOM引用
const chartRef = ref(null);
// 图表实例
let chartInstance = null;

// 初始化图表
const initChart = () => {
  // 窗口大小变化时，重新调整图表大小
  window.addEventListener("resize", resizeChart);

  // 更新图表数据
  updateChart();
};

// 更新图表数据
const updateChart = () => {
  if (!chartInstance) return;

  // 提取数据
  const types = typeData.value.map((item) => item.type);
  const counts = typeData.value.map((item) => item.count);

  // 图表配置项
  const option = {
    backgroundColor: document.documentElement.classList.contains("dark")
      ? "#192e4f"
      : "#fff",
    title: {
      text: props.title,
      left: "left",
      textStyle: {
        color: document.documentElement.classList.contains("dark")
          ? "#DCDEE2"
          : "#333",
        fontSize: 14,
        fontWeight: 500,
        letterSpacing: 5,
      },
      top: 0,
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    grid: {
      left: "0%",
      right: "4%",
      bottom: "10%",
      top: "15%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: types,
      axisTick: {
        show: false,
      },
      axisLine: { show: true },
      lineStyle: {
        color: "#eee",
      },
      lineStyle: {
        color: "#eee",
      },
      axisLabel: {
        rotate: 0,
        interval: 0,
        color: "#999",
        fontSize: 12,
        margin: 15,
      },
    },
    yAxis: {
      type: "value",
      name: "",
      max: function (value) {
        return Math.ceil(value.max / 50) * 50;
      },
      // interval: 50,
      axisLabel: {
        color: "#999",
      },
      splitLine: { show: false },
      lineStyle: {
        type: "dashed",
        color: "#eee",
      },
      axisLine: {
        show: true,
      },
      axisTick: {
        show: false,
      },
    },
    series: [
      {
        name: "数量",
        type: "bar",
        barWidth: "28%",
        data: counts,
        itemStyle: {
          // color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          //   { offset: 0, color: '#0176F6' },
          //   { offset: 1, color: '#c1d4ff' }
          // ]),
          borderRadius: [5, 5, 0, 0],
        },
        // emphasis: {
        //   itemStyle: {
        //     color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        //       { offset: 0, color: '#0176F6' },
        //       { offset: 1, color: '#a7c1ff' }
        //     ])
        //   }
        // }
      },
    ],
  };

  // 设置图表配置
  chartInstance.setOption(option);
};

// 调整图表大小
const resizeChart = () => {
  if (chartInstance) {
    chartInstance.resize();
  }
};

// 监听数据变化，更新图表
watch(
  () => props.is_standard,
  () => {
    fetchData();
  },
  { deep: true }
);
watch(
  () => props.textColor,
  () => {
    updateChart();
  }
);
watch(
  () => props.title,
  () => {
    updateChart();
  }
);

// 组件挂载后初始化图表
onMounted(() => {
  if (!chartRef.value) return;
  // 初始化图表实例
  chartInstance = echarts.init(chartRef.value);
  fetchData(true);
});

// 组件卸载前销毁图表
onUnmounted(() => {
  if (chartInstance) {
    window.removeEventListener("resize", resizeChart);
    chartInstance.dispose();
    chartInstance = null;
  }
});
</script>

<style lang="scss" scoped>
.chart-container {
  width: 100%;
  height: v-bind(height);
  border-radius: 8px;
}
</style>
